<?php

namespace backend\components;

use Yii;
use yii\base\Component;

class UploadMedia extends Component
{
    protected $mch_id;

    protected $diy_key;

    protected $img_path = '/data/wwwroot/default/teach/backend/web/uploads/1.jpg';//被上传的图片的服务器图片

    protected $uploadUrl = 'https://api.mch.weixin.qq.com/secapi/mch/uploadmedia';

    protected $sslCertPath = '/data/wwwroot/default/teach/teach/components/cert/apiclient_cert.pem';

    protected $sslKeyPath = '/data/wwwroot/default/teach/teach/components/cert/apiclient_key.pem';

    public function __construct()
    {
        parent::__construct();

        $this->mch_id = Yii::$app->params['serviceNum']['mchId'];

        $this->diy_key = Yii::$app->params['serviceNum']['md5Key'];
    }

    public function uploadImg()
    {
        $data = [
            'mch_id' => $this->mch_id,
            'media_hash' => $this->hashMedia($this->img_path),
            'sign_type' => 'HMAC-SHA256',
            'sign' => '',
        ];
        $data['sign'] = $this->makeSign($data, $data['sign_type']);
        $data['media'] = new \CURLFile($this->img_path);
        $header = ['
             "content-type:multipart/form-data",
        '];
        $url = $this->uploadUrl;
        $result = $this->curl($data, $url, $header);
        return $this->toArray($result);


    }

    protected function hashMedia($media_addr, $type = 'md5')
    {
        return $this->media_hash ?? hash_file($type, $media_addr);
    }

    protected function makeSign(array $data, $signType = 'HMAC-SHA256')
    {
        //签名步骤一：按字典序排序参数
        ksort($data);
        $string = $this->toUrlParams($data);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . $this->diy_key;
        //签名步骤三：MD5加密或者HMAC-SHA256
        if ($signType == 'md5') {
            //如果签名小于等于32个,则使用md5验证
            $string = md5($string);
        } else {
            //是用sha256校验
            $string = hash_hmac("sha256", $string, $this->diy_key);
        }
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    protected function toUrlParams(array $data)
    {
        $buff = "";
        foreach ($data as $k => $v) {
            if ($k != "sign" && $v !== "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
    /**
     * 输出xml字符
     * @param $data
     * @return string
     * @throws \Exception
     */
    protected function toXml($data)
    {
        if (!is_array($data) || count($data) <= 0) {
            throw new \Exception('xml解析错误');
        }
        $xml = "<xml>";
        foreach ($data as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * xml转数组
     * @param $xml
     * @return mixed
     */
    public function toArray($xml)
    {
        //禁止引用外部xml实体
        //libxml_disable_entity_loader(true);
        $xmlString = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $val = json_decode(json_encode($xmlString), true);
        return $val;
    }

    public function curl($param = "", $url, $headers)
    {
        $postUrl = $url;
        $curlPost = $param;
        $ch = curl_init();                   //初始化curl
        curl_setopt($ch, CURLOPT_URL, $postUrl);         //抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER, 0);          //设置header
        //curl_setopt($ch, CURLOPT_HEADER, $headers);          //设置header
        //curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);      //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_POST, 1);           //post提交方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);      // 增加 HTTP Header（头）里的字段
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);    // 终止从服务端进行验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSLCERT, $this->sslCertPath); //这个是证书的位置
        curl_setopt($ch, CURLOPT_SSLKEY, $this->sslKeyPath); //这个也是证书的位置
        $data = curl_exec($ch);                 //运行curl
        curl_close($ch);
        return $data;
    }
}